﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using umbraco.interfaces;
using System.Xml;
using umbraco.cms.businesslogic.packager.standardPackageActions;

namespace uForum.PackageActions
{
    public class Add404Handler : IPackageAction
    {
        #region IPackageAction Members

        public string Alias()
        {
            return "Add404Handler";
        }

        public bool Execute(string packageName, System.Xml.XmlNode xmlData)
        {
            bool result = false;

            //Get attribute values
            string handlerAssembly = XmlHelper.GetAttributeValueFromNode(xmlData, "assembly");
            string handlerType = XmlHelper.GetAttributeValueFromNode(xmlData, "type");

            //Open the Umbraco Settings config file
            XmlDocument umbraco404HandlersFile = umbraco.xmlHelper.OpenAsXmlDocument("/config/404handlers.config");

            //Select scheduled tasks node from the settings file
            XmlNode handlersRootNode = umbraco404HandlersFile.SelectSingleNode("//NotFoundHandlers");

            //Create a new scheduled task node 
            XmlNode handlerNode = (XmlNode)umbraco404HandlersFile.CreateElement("notFound");

            //Append addributes
            handlerNode.Attributes.Append(umbraco.xmlHelper.addAttribute(umbraco404HandlersFile, "assembly", handlerAssembly));
            handlerNode.Attributes.Append(umbraco.xmlHelper.addAttribute(umbraco404HandlersFile, "type", handlerType));

            //Append the new rewrite scheduled task to the Umbraco Settings config file
            handlersRootNode.InsertBefore(handlerNode, handlersRootNode.SelectSingleNode("//notFound[@assembly = 'umbraco' and @type = 'SearchForProfile']"));

            //Save the Umbraco Settings config file with the new Scheduled task
            umbraco404HandlersFile.Save(System.Web.HttpContext.Current.Server.MapPath("/config/404handlers.config"));

            //No errors so the result is true
            result = true;

            return result;
        }

        public System.Xml.XmlNode SampleXml()
        {
            string sample = "<Action runat=\"install\" alias=\"Add404Handler\" assembæy=\"myassemblyname\" type=\"myhandlertype\"></Action>";
            return helper.parseStringToXmlNode(sample);
        }

        public bool Undo(string packageName, System.Xml.XmlNode xmlData)
        {
            bool result = false;
            //Get alias to remove
            string handlerAssemblyAlias = XmlHelper.GetAttributeValueFromNode(xmlData, "assembly");
            string handlerTypeAlias = XmlHelper.GetAttributeValueFromNode(xmlData, "type");

            //Open the Umbraco Settings config file
            XmlDocument umbraco4040HanldersFile = umbraco.xmlHelper.OpenAsXmlDocument("/config/404handlers.config");

            //Select scheduled tasks root node from the settings file
            XmlNode handlersNode = umbraco4040HanldersFile.SelectSingleNode("//NotFoundHandlers");

            //Get the child node with the scheduled task we want to remove
            //Select the url rewrite rule by name from the config file
            XmlNode scheduledTaskNode = handlersNode.SelectSingleNode("//notFound[@assembly = '" + handlerAssemblyAlias + "' and @type = '" + handlerTypeAlias +"']");

            if (scheduledTaskNode != null)
            {
                //Child node is not null, remove it
                handlersNode.RemoveChild(scheduledTaskNode);

                //Save the modified configuration file
                umbraco4040HanldersFile.Save(System.Web.HttpContext.Current.Server.MapPath("/config/404handlers.config"));
            }

            return result;
        }

        #endregion
    }

    public class XmlHelper
    {
        /// <summary>
        /// Gets the value from an attribute or returns an empty string if it wasn't specified
        /// </summary>

        public static string GetAttributeValueFromNode(XmlNode node, string attributeName)
        {
            string result = string.Empty;

            if (node.Attributes[attributeName] != null)
            {
                //Attribute has an value return that.
                result = node.Attributes[attributeName].InnerText;
            }
            return result;
        }

    }
}
